#!/usr/bin/env node
const path = require('path');
const fs = require('fs');
const { program } = require('commander');
const { execSync } = require('child_process');
const { exit } = require('process');

console.log(`开始发布npm模板包......`);
const tempPath = path.resolve(path.join(__dirname, '../../temp'));
program.option('-p, --project <project-path>', '项目目录').parse(process.argv);
const { project } = program.opts();
if (!project) {
  console.log('请指定发布项目目录');
  exit(1);
}

const projectPath = path.resolve(project);

// 检查temp目录是否存在，如果不存在则创建
if (!fs.existsSync(tempPath)) {
  fs.mkdirSync(tempPath, { recursive: true }); // 使用 recursive 选项创建多级目录
} else {
  fs.rmSync(tempPath, { recursive: true, force: true }); // 递归删除目录及其内容
  fs.mkdirSync(tempPath, { recursive: true });
}

const excludePaths = [
  path.join(projectPath, 'template'),
  path.join(projectPath, 'node_modules'),
  path.join(projectPath, 'dist'),
  path.join(projectPath, 'out'),
  path.join(projectPath, 'src/publish'),
];

function copyFiles(projectPath, targetDir, excludePaths) {

  // 要拷贝的目录不存在，则创建
  if (!fs.existsSync(targetDir)) {
    fs.mkdirSync(targetDir);
  }

  // 读取源目录中的所有文件和文件夹
  const items = fs.readdirSync(projectPath);

  items.forEach(item => {
    const sourcePath = path.join(projectPath, item);
    const targetPath = path.join(targetDir, item);

    // 排除指定的目录不拷贝
    if (excludePaths && excludePaths.includes(sourcePath)) {
      return;
    }

    const stats = fs.lstatSync(sourcePath);

    if (stats.isDirectory()) {
      // 如果是目录，递归拷贝该目录下的所有文件和文件夹
      if (!fs.existsSync(targetPath)) {
        fs.mkdirSync(targetPath);
      }
      copyFiles(sourcePath, targetPath);
    } else if (stats.isFile()) {
      // 如果是文件，直接拷贝文件到目标目录
      fs.copyFileSync(sourcePath, targetPath);
      console.log(`Copied file path: ${targetPath}`);
    }
  });
}

// 拷贝静态资源和模版，排除已发布的文件和其他编译目录
console.group('STAGE1:拷贝静态资源');
copyFiles(projectPath, path.join(tempPath, 'static'), excludePaths);
console.groupEnd('STAGE1:拷贝静态资源');

console.group('STAGE2:拷贝模板资源');
copyFiles(
  path.join(projectPath, 'template'),
  path.join(tempPath, 'template'),
);
console.groupEnd('STAGE2:拷贝模板资源');


// *修改版本号和@ibizlab/cli版本号
console.group('STAGE3:准备发布包资源');
let projectPackageJson;
try {
  const data = fs.readFileSync(path.join(projectPath, 'package.json'), 'utf8');
  projectPackageJson = JSON.parse(data);
} catch (error) {
  console.error('获取项目package.json出错：', error);
  exit(1);
}
const jsonData = require('./resource.json');
// 统一版本号
jsonData.version = projectPackageJson.version;
// 修改@ibizlab/cli版本号
if(projectPackageJson.devDependencies && projectPackageJson.devDependencies['@ibizlab/cli']){
  jsonData.dependencies['@ibizlab/cli'] = projectPackageJson.devDependencies['@ibizlab/cli'];
}
fs.writeFileSync(
  path.join(tempPath, 'package.json'),
  JSON.stringify(jsonData, null, 2),
);
console.log(`修改主项目版本号（${jsonData.version}）、@ibizlab/cli版本号（${jsonData.dependencies['@ibizlab/cli']}）成功`);

// *删除.gitignore里的publish src/publish/**
try {
  const str = fs.readFileSync(path.join(tempPath, 'static/.gitignore'), 'utf8');
  fs.writeFileSync(path.join(tempPath, 'static/.gitignore.bak'), str.replace('src/publish/**', '').replace('public/static/**/*.json\n', '').replace('# 发布文件\n', ''));
} catch (error) {
  console.error('获取项目.gitignore出错：', error);
  exit(1);
}
console.log(`修改项目.gitignore文件成功`);

// *拷贝template目录下的脚本到temp的src下
copyFiles(
  path.resolve(path.join(__dirname, '../template')),
  path.join(tempPath, 'src'),
);
console.log(`拷贝模板发布代码脚本成功`);
console.groupEnd('STAGE3:准备发布包资源');

// 设置要发布的包的目录
console.group('STAGE4:发布npm模板包');
try {
  // 同步执行 npm publish 命令
  const result = execSync('npm run publish:npm', { cwd: tempPath });
  console.log(`发布npm模板包成功`);
  console.log(result.toString());
} catch (error) {
  // 捕获并处理错误
  console.error('发布npm模板包失败', error.stderr ? error.stderr.toString() : error.toString());
}
console.groupEnd('STAGE4:发布npm模板包');

// 结束后删除临时目录
fs.rmSync(tempPath, { recursive: true, force: true }); // 递归删除目录及其内容
console.log(`结束发布npm模板包......`);

